▶︎ 디폴트 네트워크
기본적으로 Docker Compose는 하나의 디폴트 네트워크에 모든 컨테이너를 연결한다.
디폴트 네트워크의 이름은 docker-compose.yml
가 위치한 디렉토리 이름 뒤에 _default
가 붙는다.
예를 들어보자면, 디렉토리 이름이 my_app
라면 디폴트 네트워크 이름은 my_app_default
가 된다.
컨테이너 간 통신
디폴트 네트워크 안에서 컨테이너 간의 통신에서는 서비스의 이름이 호스트명으로 사용된다.
얘를 들어보자면, web
서비스의 컨테이너에서 db
서비스의 컨테이너를 대상으로 ping
명령어를 날릴수 있다.
$ docker-compose exec web ping db
64 bytes from 172.21.0.3: seq=0 ttl=64 time=0.221 ms
64 bytes from 172.21.0.3: seq=1 ttl=64 time=0.271 ms
64 bytes from 172.21.0.3: seq=2 ttl=64 time=0.367 ms
컨테이너 간 통신에서 주의할 점은 접속하는 위치가 디폴트 네트워크 내부냐 외부냐에 따라서 포트가 달라질 수 있다는 것이다.
예를 들자면, docker-compose.yml
에 web
서비스의 ports
설정이 아래와 같다면
services:
web:
build: .
ports:
- "8001:80"
호스트 컴퓨터에서 접속할 때는 8001
포트를 사용해야 하고, 같은 디폴트 네트워크 내의 다른 컨테이너에서 접속할 때는 포트 80
을 사용해야 한다
호스트 컴퓨터에서 web
서비스 컨테이너 접속
$ curl -I localhost:8001
HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: text/html; charset=utf-8
Content-Length: 480
ETag: W/"1e0-h+XZDnSzOoZPcJZ0k/AXKtDL92Y"
Date: Wed, 19 Apr 2023 05:36:19 GMT
Connection: keep-alive
Keep-Alive: timeout=5
같은 네트워크 내의 다른 컨테이너에서 web
서비스 컨테이너 접속
$ docker-compose exec db curl -I web:80
HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: text/html; charset=utf-8
Content-Length: 480
ETag: W/"1e0-h+XZDnSzOoZPcJZ0k/AXKtDL92Y"
Date: Wed, 19 Apr 2023 05:59:41 GMT
Connection: keep-alive
Keep-Alive: timeout=5
▶︎ 커스텀 네트워크 추가
디폴트 네트워크 뿐만 아니라 다른 네트워크도 필요에 따라 추가해줄 수 있다
docker-compose.yml
의 networks
항목 아래에 my_net
이라는 네트워크를 추가하고, web
서비스의 networks
항목 아래에 my_net
네트워크를 추가하자.
이렇게 설정을 하게되면 db
서비스는 디폴트 네트워크에만 연결되지만, web
서비스는 디폴트 네트워크 뿐만 아니라 my_net
네트워크에도 연결되게 된다!
services:
web:
image: yshrim12/web:1.0
ports:
- "8000:80"
networks:
- default
- my_net
db:
image: yshrim12/mysql:1.0
env_file:
- ".mysql.env"
networks:
my_net:
driver: bridge
Docker Compose로 애플리케이션을 올려보면 두 개의 네트워크가 생성되는 것을 알 수 있다!
$ docker-compose up -d
[+] Running 4/4
⠿ Network git_default Created 0.0s
⠿ Network git_my_net Created 0.0s
⠿ Container web Started 0.4s
⠿ Container db Started 0.3s
$ docker network ls | grep "my_net"
43bf22905641 git_my_net bridge local
my_net
은 Docker Compose 내부에서 정의된 네트워크 이므로 애플리케이션을 내릴 때 디폴트 네트워크와 함께 삭제된다
▶︎ 외부 네트워크 사용 #1
Docker Compose가 제공하는 디폴트 네트워크 대신에 외부에서 미리 생성해놓은 다른 네트워크를 사용할 수도 있다
먼저 my_net
이라는 네트워크를 별도로 생성하자
$ docker network create my_net
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
01148fff8c35 bridge bridge local
0a5d707b4146 host host local
13431a24edc8 my_net bridge local
c3356923ba47 none null local
그 다음, docker-compose.yml
에서 default
네트워크의 name
키에 대한 값으로 위에서 생성했던 my_net
도커 네트워크를 기입하면 된다
networks:
default:
name: my_net
이제 Docker Compose로 애플리케이션을 올리고 my_net
네트워크의 상세 정보를 확인해보면 Container
항목에 두 개의 컨테이너가 연결된 것을 알 수가 있다.
$ docker-compose up -d
[+] Running 2/2
⠿ Container db Started 0.4s
⠿ Container web Started 0.5s
$ docker network inspect my_net
(...생략...)
"Containers": {
"434906917dbf5efac9555faab3897671b47790e5aa110995944e0f86134edd61": {
"Name": "web",
"EndpointID": "7f9a5f7597f30ec1dd12d732a720ea81cfb6586422db68e1013cacdbe037d953",
"MacAddress": "02:42:ac:1c:00:03",
"IPv4Address": "172.28.0.3/16",
"IPv6Address": ""
},
"48c84ade3458f86ad2574a84d60e67a59aaa025bb42fd1df00bfe42ab923c6ac": {
"Name": "db",
"EndpointID": "afe11491820864394330a22c4aba175457225f43e2a1fbf888fbe3b9a72721c2",
"MacAddress": "02:42:ac:1c:00:02",
"IPv4Address": "172.28.0.2/16",
"IPv6Address": ""
}
},
(...생략...)
▶︎ 외부 네트워크 사용 #2
이번에는 react-net
이라는 도커 네트워크를 생성하자.
$ docker network create react-net
위에서 생성한 도커 네트워크를 docker compose 내 특정 컨테이너만 소속하도록 코드를 작성해보자.
version: "3"
services:
mongodb:
image: mongo:latest
networks:
- my-react-net
backend:
image: yshrim12/backend:latest
networks:
- my-react-net
frontend:
image: yshrim12/frontend:latest
networks:
my-react-net:
name: react-net
external: true
각 서비스에 대한 설명은 다음과 같다
-
mongodb: MongoDB 데이터베이스를 실행하는 Docker 이미지를 사용함.
mongo:latest
이미지를 기반으로 하며,my-react-net
네트워크에 속하도록 지정되어 있음. -
backend: 백엔드 서버를 실행하는 Docker 이미지를 사용함.
yshrim12/backend:latest
이미지를 기반으로 하며,my-react-net
네트워크에 속하도록 지정되어 있음. -
frontend: 프론트엔드 서버를 실행하는 Docker 이미지를 사용함.
yshrim12/frontend:latest
이미지를 기반으로 하며, 명시적으로 네트워크에 속하지 않았기 때문에 기본적으로 default 네트워크에 속하게 된다. -
마지막으로,
my-react-net
이라는 Docker 네트워크를 정의한다. 이 네트워크는react-net
이라는 이름으로 생성되며, 외부 네트워크로 설정되어 있고, 이는 다른 Docker Compose 파일에서 정의된 네트워크를 재사용하기 위함이다.
‣ 네트워크 공유
기본적으로 docker의 경우 컨테이너를 구동할 때 사설 네트워크를 자동으로 만들어 각 컨테이너간 격리가 되고,
docker-compose의 경우 실행 디렉토리의 이름으로 네트워크를 만들어 docker-compose 네트워크 간 격리가 이뤄지게 된다.
여기서 알아볼 것은 docker-compose를 여러 개 사용할 때 하나의 network로 통합해 운영하는 방법에 대해서 다룰거다.
알고있듯이 위처럼 컨테이너들에 대해서 네트워크를 통합하는 것의 장점은 서비스간 서비스명(container_name)으로 통신이 가능해진다는 점이다. 호스트에서 컨테이너의 포트를 오픈해줄 필요가 없다는 뜻이기도 하다.
먼저 통합될 도커 네트워크를 생성해줘야 한다.
# docker network create bridge [네트워크 이름]
$ docker network create bridge test-network
그 후 설정은 간단하다. docker-compose 설정 맨 아래 부분에 네트워크 부분만 추가해주면 된다.
# ... [서비스 코드] ...
networks:
default:
external: true
name: test-network